<?php

namespace app\admin\model;

use app\admin\enum\CouponAssignType;
use app\admin\enum\CouponGetType;
use app\admin\enum\CouponRecordStatus;
use app\admin\enum\CouponStatus;
use app\common\controller\Backend;
use think\Db;
use think\Model;
use traits\model\SoftDelete;

class Coupon extends Model
{
    use SoftDelete;
    // 表名
    protected $name = 'coupon';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [

    ];


    public function getTypeList()
    {
        return [
            'VOUCHER'  => __('Type VOUCHER'),
            'FULL'     => __('Type FULL'),
            'DISCOUNT' => __('Type DISCOUNT'),
        ];
    }

    public function getGetTypeList()
    {
        return [
            '1'  => __('get_type index'),
            '2' => __('get_type assign'),
        ];
    }

    public function getAssignTypeList()
    {
        return [
            'none'  => __('assign_type none'),
            'users' => __('assign_type users'),
        ];
    }

    public function getStatusList()
    {
        return ['0' => __('Status 0'), '1' => __('Status 1'), '2' => __('Status 2')];
    }


    public function getTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
        $list  = $this->getTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getStartTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['start_time']) ? $data['start_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getEndTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['end_time']) ? $data['end_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list  = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    protected function setStartTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    protected function setEndTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }


    public function zone()
    {
        return $this->belongsTo('Zone', 'zone_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    /**
     * 领取优惠券
     * @param $coupon_id
     * @param $user_id
     * @return CouponRecordModel
     */
    public static function takeCoupon($coupon_id, $user_id)
    {
        $coupon = self::get($coupon_id);
        if (!$coupon) {
            fail('优惠券不存在');
        }
        if ($coupon['status'] != CouponStatus::NORMAL) {
            fail('优惠券状态异常');
        }
//        if ($coupon['stocks'] <= 0) {
//            tongcheng_fail('优惠券已领完');
//        }
        if ($coupon['start_time'] > time()) {
            fail('优惠券未到领取时间');
        }
        if ($coupon['end_time'] < time()) {
            fail('优惠券已过期');
        }

        $user_coupon_count = CouponRecord::where('coupon_id', $coupon_id)->where('user_id', $user_id)->count();
        if ($user_coupon_count >= 1) {
            fail('您已超过该优惠券的领取次数');
        }

        $unused_count = CouponRecord::where('coupon_id', $coupon_id)->where('user_id', $user_id)->where('status', CouponRecordStatus::UNUSED)->count();
        if ($unused_count > 0) {
            fail('存在该优惠券未使用的优惠券记录');
        }

        return Db::transaction(function () use ($coupon, $user_id) {
            // 更新优惠券库存
            $table_name = $coupon->getTable();
            $sql        = "UPDATE `{$table_name}` SET `stocks` = `stocks` - 1, `get_count` = `get_count` + 1 WHERE `id` = {$coupon['id']} AND `stocks` > 0";
            Db::execute($sql);

            // 创建优惠券记录
            return CouponRecord::create([
                'zone_id'     => $coupon['zone_id'],
                'coupon_id'   => $coupon['id'],
                'user_id'     => $user_id,
                'type'        => $coupon['type'],
                'name'        => $coupon['name'],
                'money'       => $coupon['money'],
                'min_money'   => $coupon['min_money'],
                'discount'    => $coupon['discount'],
                'expire_time' => $coupon['expire_day'] * 86400 + time(),
                'status'      => CouponRecordStatus::UNUSED,
                'get_type'    => CouponGetType::INDEX,
            ]);
        });
    }

    /**
     * 使用优惠券
     * @param $coupon_id
     * @param $coupon_record_id
     * @return void
     */
    public static function useCoupon( $coupon_record_id)
    {
        // 更新优惠券使用次数
        //self::where('id', $coupon_id)->setInc('used_count');

        // 更新优惠券记录状态
        CouponRecord::update([
            'status' =>1,
        ], [
            'id' => $coupon_record_id,
        ]);
    }

    /**
     * 指定用户发放优惠券
     * @param $coupon
     * @return false
     * @throws \Exception
     */
    public static function assignCoupon($coupon)
    {
        // 非指定发放方式
        if ($coupon['get_type'] != CouponGetType::ASSIGN) {
            return false;
        }
        // 指定发放用户为空
        if ($coupon['assign_type'] == CouponAssignType::USERS && empty($coupon['assign_user_ids'])) {
            return false;
        }

        $user_ids = [];
        if ($coupon['assign_type'] == CouponAssignType::ZONE) {
            $user_ids = User::where('zone_id', $coupon['zone_id'])->column('id');
        } else if ($coupon['assign_type'] == CouponAssignType::USERS) {
            $user_ids = explode(',', $coupon['assign_user_ids']);
        }

        if (empty($user_ids)) {
            return false;
        }

        $data = [];
        foreach ($user_ids as $user_id) {
            for ($i = 0; $i < $coupon['total']; $i++) {
                $data[] = [
                    'zone_id'     => $coupon['zone_id'],
                    'coupon_id'   => $coupon['id'],
                    'user_id'     => $user_id,
                    'type'        => $coupon['type'],
                    'name'        => $coupon['name'],
                    'money'       => $coupon['money'],
                    'min_money'   => $coupon['min_money'],
                    'discount'    => $coupon['discount'],
                    'expire_time' => $coupon['expire_day'] * 86400 + time(),
                    'status'      => CouponRecordStatus::UNUSED,
                    'get_type'    => CouponGetType::ASSIGN,
                ];
            }
        }

        Db::startTrans();
        try {
            (new CouponRecord)->saveAll($data);

            $coupon->stocks    = 0;
            $coupon->get_count = count($data) * $coupon['total'];
            $coupon->status    = CouponStatus::STOCK_OUT;
            $result            = $coupon->save();

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return false;
        }

        return $result;
    }
}
